﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Ams.Extensions
{
    public class SmartDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    {
        public TValue NullObject = default(TValue);

        public SmartDictionary(TValue notFoundValue)
        {
            NullObject = notFoundValue;
        }

        public SmartDictionary(IDictionary<TKey, TValue> dictionary)
            : base(dictionary)
        {

        }

        public SmartDictionary(IDictionary<TKey, TValue> dictionary, TValue notFoundValue)
            : base(dictionary)
        {
            NullObject = notFoundValue;
        }

        public new TValue this[TKey key]
        {
            get { return ContainsKey(key) ? base[key] : NullObject; }
            set { if (ContainsKey(key)) base[key] = value; else Add(key, value); }
        }
    }

    public static class SmartDictionyExtentions
    {
        public static SmartDictionary<TKey, TValue> ToSmartDictionary<TKey, TValue>(this IEnumerable<TValue> enumerable, Func<TValue, TKey> keySelector)
        {
            return new SmartDictionary<TKey, TValue>(enumerable.ToDictionary(keySelector));
        }

        public static SmartDictionary<TKey, TValue> ToSmartDictionary<TKey, TValue>(this IEnumerable<TValue> enumerable, Func<TValue, TKey> keySelector, TValue notFountValue)
        {
            return new SmartDictionary<TKey, TValue>(enumerable.ToDictionary(keySelector));
        }

        public static SmartDictionary<TKey, TValue> ToSmartDictionary<TKey, TValue, TIn>(this IEnumerable<TIn> enumerable, Func<TIn, TKey> keySelector, Func<TIn, TValue> valueSelector)
        {
            return new SmartDictionary<TKey, TValue>(enumerable.ToDictionary(keySelector, valueSelector));
        }

        public static SmartDictionary<TKey, TValue> ToSmartDictionary<TKey, TValue, TIn>(this IEnumerable<TIn> enumerable, Func<TIn, TKey> keySelector, Func<TIn, TValue> valueSelector, TValue notFoundValue)
        {
            return new SmartDictionary<TKey, TValue>(enumerable.ToDictionary(keySelector, valueSelector), notFoundValue);
        }
    }
}
